Skip to content

feat: publish global → proj_frame FrameTransform from proj_frame_offset#200

Open
jdsika wants to merge 2 commits into
mainfrom
feat/proj-frame-transform
Open

feat: publish global → proj_frame FrameTransform from proj_frame_offset#200
jdsika wants to merge 2 commits into
mainfrom
feat/proj-frame-transform

Conversation

@jdsika

@jdsika jdsika commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

When GroundTruth.proj_frame_offset is present, publish an additional FrameTransform connecting the OSI "global" frame to the geographic CRS world frame "proj_frame".

This keeps "global" as the frame tree root (consistent with existing ego transforms) and enables Lichtblick to resolve OpenDRIVE map geometry (in "proj_frame") alongside OSI objects (in "global") through a shared tree.

Changes

  • New FrameTransform: parent="global", child="proj_frame" with inverted proj_frame_offset (using invertQuaternion + pointRotationByQuaternion from @utils/math)
  • New constant: OSI_PROJ_FRAME = "proj_frame" in frameTransformNames.ts with documentation
  • Dependencies: Added proj4 + @types/proj4 for future CRS normalization
  • Tests: 4 new tests covering presence/absence of proj_frame_offset, zero yaw, and inverted offset math
  • yarn.lock: Regenerated to resolve from public registry.yarnpkg.com (was pointing to internal BMW Artifactory)

Architecture: Shared "proj_frame" Convention

Both plugins independently publish to/from a shared frame called "proj_frame":

  • This converter: publishes FrameTransform(parent="global", child="proj_frame") — inverted offset places proj_frame as child of global
  • OpenDRIVE converter: publishes map geometry with frame_id="proj_frame"

Frame tree (when proj_frame_offset is present):

global (root — OSI inertial frame)
├── ego_vehicle_bb_center
│     └── ego_vehicle_rear_axle
└── proj_frame (CRS world — OpenDRIVE map entities)

Why invert the offset?

GroundTruth.proj_frame_offset defines where global's origin sits in proj_frame coordinates. Since we publish parent="global", child="proj_frame", we need the inverse: where proj_frame's origin sits in global. The inversion uses existing helpers from @utils/math.

Related

Summary by CodeRabbit

  • New Features

    • Support for an optional projection-frame transform to align coordinates with map geometry when an alignment offset is provided.
  • Dependencies

    • Added proj4 and its type definitions for projection handling.
  • Tests

    • Extended frame-transform tests to cover projection-frame offset scenarios.
  • Documentation

    • Added a guideline to keep docs and code comments in sync when changing frame names or output formats.

@jdsika jdsika requested a review from thomassedlmayer as a code owner June 8, 2026 12:51
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d0777c62-eeb1-410b-814e-1ddd87887af5

📥 Commits

Reviewing files that changed from the base of the PR and between bf2d1cc and 22eb3dd.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (5)
  • AGENTS.md
  • package.json
  • src/config/frameTransformNames.ts
  • src/converters/groundTruth/frameTransformConverter.ts
  • tests/frameTransformConverter.spec.ts
✅ Files skipped from review due to trivial changes (3)
  • src/config/frameTransformNames.ts
  • AGENTS.md
  • package.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/frameTransformConverter.spec.ts
  • src/converters/groundTruth/frameTransformConverter.ts

📝 Walkthrough

Walkthrough

Adds proj_frame support: a new proj_frame frame name, conditional emission of a proj_frame→global FrameTransform from GroundTruth.proj_frame_offset (position→translation, yaw→rotation), devDependencies for proj4, tests covering emission and edge cases, and a docs drift guideline.

Changes

proj_frame_offset Frame Transform Support

Layer / File(s) Summary
Dependencies for proj4 support
package.json
Added proj4 and @types/proj4 development dependencies.
proj_frame constant
src/config/frameTransformNames.ts
Exported OSI_PROJ_FRAME = "proj_frame" with a doc comment describing the proj_frame convention.
proj_frame_offset frame conversion
src/converters/groundTruth/frameTransformConverter.ts
Added OSI_PROJ_FRAME import, updated convertGroundTruthToFrameTransforms to append a proj_frame -> global FrameTransform when proj_frame_offset.position exists, and implemented buildProjFrameTransform to map position and yaw to translation and rotation (parent=global, child=proj_frame).
Tests for proj_frame_offset behavior
tests/frameTransformConverter.spec.ts
Added tests verifying transform emission when position exists, omission when proj_frame_offset is missing or position is missing, translation values, and identity quaternion for zero yaw.
Documentation drift check
AGENTS.md
Added guideline reminding to update docs and code comments when behavior or frame names change.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hop from proj to global with delight,
Position maps true and yaw spins just right.
Tests keep me steady, deps keep me sound,
A tiny transform—alignment found.
Hooray for frames that line up tight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding publication of a global → proj_frame FrameTransform when proj_frame_offset is present, which is the core feature of this PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/proj-frame-transform

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/frameTransformConverter.spec.ts (1)

202-204: ⚡ Quick win

Avoid order-coupled assertions for the proj transform.

Using result.transforms[2] makes these tests brittle. Prefer locating the transform by parent_frame_id === "proj_frame" and child_frame_id === "global".

[details]

Proposed test hardening
-    const projTransform = result.transforms[2]!;
+    const projTransform = result.transforms.find(
+      (t) => t.parent_frame_id === "proj_frame" && t.child_frame_id === "global",
+    )!;
[/details]

Also applies to: 240-241

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/frameTransformConverter.spec.ts` around lines 202 - 204, The assertions
are brittle because they rely on a fixed index into result.transforms; instead,
find the transform object by searching result.transforms for an entry where
parent_frame_id === "proj_frame" && child_frame_id === "global" (e.g., assign
projTransform = result.transforms.find(t => ...)) and assert its properties; do
the same replacement for the other occurrence that currently uses
result.transforms[?] (the assertions around the second proj transform) so tests
are order-independent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/config/frameTransformNames.ts`:
- Around line 10-12: The comment in src/config/frameTransformNames.ts
incorrectly documents the transform direction; update the comment that currently
reads `"global" → "proj_frame"` to reflect the actual emitted FrameTransform
with parent="proj_frame" and child="global" (i.e., "proj_frame" → "global"), and
mention GroundTruth.proj_frame_offset and the FrameTransform emission so readers
understand the correct parent/child frame IDs.

In `@src/converters/groundTruth/frameTransformConverter.ts`:
- Around line 183-187: The docblock in
src/converters/groundTruth/frameTransformConverter.ts incorrectly instructs that
parent="proj_frame", child="global" uses an "INVERTED offset", which contradicts
the implementation that publishes offset/yaw as-is; update the comment to remove
the “INVERTED offset” guidance and clearly state the single correct convention
(either parent="proj_frame", child="global" with offset published as-is, or
equivalently parent="global", child="proj_frame" with the unchanged offset) so
the prose matches the actual behavior in the frameTransformConverter logic.

---

Nitpick comments:
In `@tests/frameTransformConverter.spec.ts`:
- Around line 202-204: The assertions are brittle because they rely on a fixed
index into result.transforms; instead, find the transform object by searching
result.transforms for an entry where parent_frame_id === "proj_frame" &&
child_frame_id === "global" (e.g., assign projTransform =
result.transforms.find(t => ...)) and assert its properties; do the same
replacement for the other occurrence that currently uses result.transforms[?]
(the assertions around the second proj transform) so tests are
order-independent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a252e407-3560-4908-9ce7-c351310e906f

📥 Commits

Reviewing files that changed from the base of the PR and between acd55de and 9ff6b0a.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (4)
  • package.json
  • src/config/frameTransformNames.ts
  • src/converters/groundTruth/frameTransformConverter.ts
  • tests/frameTransformConverter.spec.ts

Comment thread src/config/frameTransformNames.ts Outdated
Comment thread src/converters/groundTruth/frameTransformConverter.ts Outdated
jdsika added 2 commits June 8, 2026 17:13
Add proj_frame support to the OSI GroundTruth FrameTransform converter.
When GroundTruth.proj_frame_offset is present, a FrameTransform is
emitted with parent=global, child=proj_frame (inverted offset).

This keeps 'global' as the frame tree root and enables Lichtblick to
resolve OpenDRIVE map geometry (in frame_id='proj_frame') alongside
OSI moving objects (in frame_id='global') through a shared tree:

  global (root)
  ├── ego_vehicle_bb_center → ego_vehicle_rear_axle
  └── proj_frame (CRS world)

The inversion uses existing math helpers (invertQuaternion,
pointRotationByQuaternion) from @utils/math.

Also regenerates yarn.lock to resolve from public registry
(registry.yarnpkg.com) instead of internal BMW Artifactory.

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
Ensure agent instructions remind contributors to check for
documentation drift when implementing features.

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
@jdsika jdsika force-pushed the feat/proj-frame-transform branch from bf2d1cc to 22eb3dd Compare June 8, 2026 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant